package com.slavic.hors.admin.api.controller.portal;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.slavic.hors.admin.api.dto.portal.user.request.*;
import com.slavic.hors.admin.api.dto.portal.user.response.LoginResponse;
import com.slavic.hors.admin.api.dto.portal.user.response.RoleResponse;
import com.slavic.hors.orm.entity.*;
import com.slavic.hors.service.CommonFileDiskService;
import com.slavic.hors.service.PortalRoleService;
import com.slavic.hors.service.PortalUserService;
import com.slavic.veles.base.response.EntryHeader;
import com.slavic.veles.base.response.ResponseEntity;
import com.slavic.veles.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("portal/user")
public class UserController {

    @Autowired
    private PortalUserService portalUserService;

    @Autowired
    private PortalRoleService portalRoleService;

    @Autowired
    private CommonFileDiskService commonFileDiskService;

    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ResponseEntity<LoginResponse> login(@Validated LoginRequest request) {
        HorsPortalUser user = portalUserService.findByUserNameAndPwd(request.getUsername(), request.getPassword());
        AssertUtil.assertTrue(null != user ,"密码错误或用户不存在");
        AssertUtil.assertTrue(1 == user.getUserStatus(),"账号已停用,如有疑问,请联系管理员");
        portalUserService.saveLoginRecord(user.getId());
        return ResponseEntity.SUCCESS(LoginResponse.builder()
                .username(user.getUsername())
                .avatarUrl(user.getAvatarUrl())
                .token(JwtUtils.createToken(user.getId().toString()))
                .nickName(user.getNickName())
                .build());
    }

    @RequestMapping(value = "getUserInfo", method = RequestMethod.GET)
    public ResponseEntity<Map<String, Object>> getUserInfo() {
        Map<String, Object> map = new HashMap<>();
        String token = SpringContextHolder.getRequest().getHeader("token");
        AssertUtil.assertTrue(StringUtils.isNotBlank(token), EntryHeader.HEADER_TOKEN_INVALID);
        Long id = JwtUtils.parseObject(token, Long.class);
        AssertUtil.assertTrue(id != null, EntryHeader.HEADER_TOKEN_INVALID);
        map.put("resources",Optional.of(Optional.ofNullable(portalRoleService.userResources(id)).orElse(new ArrayList<>()).stream().map(HorsPortalResource::getResourceName).collect(Collectors.toList())).orElse(new ArrayList<>()));
        return ResponseEntity.SUCCESS(map);
    }

    @RequestMapping(value = "list", method = RequestMethod.POST)
    public ResponseEntity<PageInfo<HorsPortalUser>> list(ListRequest request) {
        return ResponseEntity.SUCCESS(PageHelper
                .startPage(request.getCurrentPage(), request.getPageSize())
                .doSelectPageInfo(() -> portalUserService.list(BeanUtil.copyObject(request,new HorsPortalUser()))));
    }

    @RequestMapping(value = "detail", method = RequestMethod.POST)
    public ResponseEntity<HorsPortalUser> detail() {
        String token = SpringContextHolder.getRequest().getHeader("token");
        AssertUtil.assertTrue(StringUtils.isNotBlank(token), EntryHeader.HEADER_TOKEN_INVALID);
        Long id = JwtUtils.parseObject(token, Long.class);
        return ResponseEntity.SUCCESS(portalUserService.findById(id));
    }

    @RequestMapping(value = "update", method = RequestMethod.POST)
    public ResponseEntity<HorsPortalUser> update(UpdateRequest request) {
        HorsPortalUser user = BeanUtil.copyObject(request, portalUserService.findById(request.getId()));
        user.setUpdateTime(new Date());
        user.setHorsVersion(user.getHorsVersion() + 1);
        return ResponseEntity.CONDITION(null != portalUserService.update(user),user,"更新用户失败");
    }

    @RequestMapping(value = "add", method = RequestMethod.POST)
    public ResponseEntity<Boolean> add(@Validated AddRequest request) {
        AssertUtil.assertTrue(null == portalUserService.findByUserName(request.getUsername()),"用户名已存在,添加用户失败");
        return ResponseEntity.CONDITION(portalUserService.add(BeanUtil.copyObject(request,new HorsPortalUser())),"添加用户失败");
    }

    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public ResponseEntity<Boolean> delete(Long id) {
        AssertUtil.assertTrue(null != id, "删除用户ID不允许为空");
        AssertUtil.assertTrue(null != portalUserService.findById(id), "用户已不存在,请刷新确认");
        return ResponseEntity.CONDITION(portalUserService.delete(id),"删除用户失败");
    }

    @RequestMapping(value = "roles", method = RequestMethod.POST)
    public ResponseEntity<RoleResponse> roles(Long id) {
        AssertUtil.assertTrue(null != id, "用户ID不能为空");
        AssertUtil.assertTrue(null != portalUserService.findById(id), "用户已不存在,请刷新确认");
        RoleResponse response = new RoleResponse();
        List<HorsPortalRole> allRoles = portalRoleService.list(new HorsPortalRole());
        AssertUtil.assertTrue(!CollectionUtils.isEmpty(allRoles), "角色列表为空,请先添加角色");
        List<HorsPortalRole> userRoles = portalRoleService.userRoles(id);
        response.setAdded(CollectionUtils.isEmpty(userRoles) ? new ArrayList<>() : userRoles);
        response.setAll(allRoles);
        return ResponseEntity.SUCCESS(response);
    }

    @RequestMapping(value = "reRoles", method = RequestMethod.POST)
    public ResponseEntity<Boolean> reRoles(@RequestBody @Validated ReRolesRequest request) {
        AssertUtil.assertTrue(null != portalUserService.findById(request.getId()), "用户已不存在,请刷新确认");
        return ResponseEntity.CONDITION(portalRoleService.reRoles(request.getId(), request.getRoleIds()),"授权失败");
    }

    @RequestMapping(value = "uploadAva", method = RequestMethod.POST)
    public ResponseEntity<Long> uploadAva(MultipartHttpServletRequest request) throws Exception{
        MultipartFile file = request.getFile("file");
        AssertUtil.assertTrue(null != file, "文件为空,请核实后上传");
        Long id = commonFileDiskService.storeFile(file.getOriginalFilename(),
                Base64Util.bytes2Base64String(file.getBytes()));
        return ResponseEntity.CONDITION(null != id,id,"头像上传失败");
    }

    @RequestMapping(value = "loginRecords", method = RequestMethod.POST)
    public ResponseEntity<List<HorsPortalLoginRecord>> loginRecords() throws Exception{
        String token = SpringContextHolder.getRequest().getHeader("token");
        AssertUtil.assertTrue(StringUtils.isNotBlank(token), EntryHeader.HEADER_TOKEN_INVALID);
        Long id = JwtUtils.parseObject(token, Long.class);
        PageHelper.startPage(1, 10);
        AssertUtil.assertTrue(id != null, EntryHeader.HEADER_TOKEN_INVALID);
        return ResponseEntity.SUCCESS(portalUserService.loginRecords(id));
    }

    @RequestMapping(value = "avatar", method = RequestMethod.GET)
    public void avatar(String id ,HttpServletResponse response) throws Exception{
        AssertUtil.assertTrue(StringUtils.isNotBlank(id),"id不允许为空");
        HorsCommonFileDisk fileDisk = commonFileDiskService.receiveFile(Long.valueOf(id));
        if (null != fileDisk) {
            response.getOutputStream().write(Base64Util.base64String2Bytes(fileDisk.getFileContent()));
            response.getOutputStream().flush();
            response.getOutputStream().close();
        }
    }
}